package com.wondertek.poms.init.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.wondertek.poms.init.message.PageBean;
import com.wondertek.poms.init.message.PageVo;
import com.wondertek.poms.init.message.RedisInfo;
import com.wondertek.poms.init.message.RedisVo;
import com.wondertek.poms.init.message.ResultBean;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;


/**
 * @author douzi
 */
@RestController
@RequestMapping("/poms-redis")
@Transactional
public class RedisController {

    /**
     * 最大获取1万个键值
     */
    private static final int maxSize = 10000;
    
    @Value("${spring.redis.cluster.nodes[0]}")
    private String ipPort;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping(value = "/getAllByPage")
    public ResultBean getAllByPage(@RequestParam(required = false) String key,
    		@RequestParam(defaultValue="1") int page,
			@RequestParam(defaultValue="20") int rows,
			@RequestParam(defaultValue="UPDATED_TIME") String sidx,
			@RequestParam(defaultValue="desc") String sord){

        List<RedisVo> list = new ArrayList<>();

        if(StrUtil.isNotBlank(key)){
            key = "*" + key + "*";
        }else{
            key = "*";
        }
        Set<String> keys = redisTemplate.keys(key);
        int size = keys.size();
        // 限制10万个
        if(size > maxSize){
            size = maxSize;
        }
        int i = 0;
        for (String s : keys) {
            if(i>size){
                break;
            }
            RedisVo redisVo = new RedisVo(s, "", redisTemplate.getExpire(s, TimeUnit.SECONDS));
            list.add(redisVo);
            i++;
        }
        PageVo pageVo = new PageVo(page, rows, sidx, sord);
        Pageable pageable = new PageRequest((page - 1), rows);
        Page<RedisVo> pages = new PageImpl<RedisVo>(listToPage(pageVo, list), pageable, size);
        pages.getContent().forEach(e->{
            String value = "";
            try {
                value =  redisTemplate.opsForValue().get(e.getKey());
                if(value.length()>150){
                    value = value.substring(0, 150) + "...";
                }
            } catch (Exception exception){
                value = "非字符格式数据";
            }
            e.setValue(value);
        });
        return PageBean.ok(pages.getTotalPages(), pages.getTotalElements(), pages.getContent());
    }
    
    /**
     * List 手动分页
     * @param page
     * @param list
     * @return
     */
    public static List<RedisVo> listToPage(PageVo page, List<RedisVo> list) {
        int pageNumber = page.getPageNumber() - 1;
        int pageSize = page.getPageSize();

        if(pageNumber<0){
            pageNumber = 0;
        }
        if(pageSize<1){
            pageSize = 10;
        }
        if(pageSize>100){
            pageSize = 100;
        }

        int fromIndex = pageNumber * pageSize;
        int toIndex = pageNumber * pageSize + pageSize;

        if(fromIndex > list.size()){
            return new ArrayList<RedisVo>();
        } else if(toIndex >= list.size()) {
            return list.subList(fromIndex, list.size());
        } else {
            return list.subList(fromIndex, toIndex);
        }
    }

    @GetMapping(value = "/getByKey/{key}")
    public ResultBean getByKey(@PathVariable String key){

        Map<String, Object> map = new HashMap<>();
        String value = redisTemplate.opsForValue().get(key);
        Long expireTime = redisTemplate.getExpire(key, TimeUnit.SECONDS);
        map.put("value", value);
        map.put("expireTime", expireTime);
        return ResultBean.ok(map);
    }

    @PostMapping(value = "/save")
    public ResultBean save(@RequestParam String key,
                               @RequestParam String value,
                               @RequestParam Long expireTime){

        if(expireTime<0){
            redisTemplate.opsForValue().set(key ,value);
        }else if(expireTime>0){
            redisTemplate.opsForValue().set(key ,value, expireTime, TimeUnit.SECONDS);
        }
        return ResultBean.ok("保存成功");
    }

    @PostMapping(value = "/delByKeys")
    public ResultBean delByKeys(@RequestParam String[] keys){

        for(String key : keys){
            redisTemplate.delete(key);
        }
        return ResultBean.ok("删除成功");
    }

    @PostMapping(value = "/delAll")
    public ResultBean delAll(){
        redisTemplate.delete(redisTemplate.keys("*"));
        return ResultBean.ok("删除成功");
    }

    @GetMapping(value = "/getKeySize")
    public ResultBean getKeySize(){

        Map<String, Object> map = new HashMap<>(16);
        map.put("keySize", redisTemplate.getConnectionFactory().getConnection().dbSize());
        map.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
        return ResultBean.ok(map);
    }

    @GetMapping(value = "/getMemory")
    public ResultBean getMemory(){
        Map<String, Object> map = new HashMap<>(16);
        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
		Properties properties = connection.info();
		List<RedisInfo> infoList = new ArrayList<>();
		Set<Object> keys = properties.keySet();
		map.put("memory", null);
		for (Object key : keys) {
			if (key.toString().endsWith("used_memory_peak_human")) {
				String value = properties.get(key).toString();
	            RedisInfo redisInfo = new RedisInfo();
	            redisInfo.setKey(key.toString());
	            redisInfo.setValue(value);
	            infoList.add(redisInfo);
	            map.put("memory", value);
			}
		}
        map.put("time", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm"));
        return ResultBean.ok(map);
    }

    @GetMapping(value = "/info")
    public ResultBean info(){

        List<RedisInfo> infoList = new ArrayList<>();
        Properties properties = redisTemplate.getConnectionFactory().getConnection().info();
        Set<Object> keys = properties.keySet();
        for(Object key : keys){
            String value = properties.get(key).toString();
            RedisInfo redisInfo = new RedisInfo();
            redisInfo.setKey(key.toString());
            redisInfo.setValue(value);
            infoList.add(redisInfo);
        }
        return ResultBean.ok(infoList);
    }
    
    public static void main(String[] args) {
		String aa = "/^poms-redis\\.(gif|jpg|jpeg|png)$/";
		String url = "http://localhost:8089/poms-redis/css/easyui/bootstrap/images/panel_tools.png";
		
	}
}
